package com.cnpc.fyspcenter.sp;

import android.content.Context;
import android.content.SharedPreferences;
import android.os.Build;
import android.text.TextUtils;
import android.util.Base64;
import android.util.Log;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.StreamCorruptedException;

/**
 * Created by bingju on 2017/1/5.
 * 此类是SharedPreference的组合实现
 * 支持存储的数据类型为：
 * Boolean、Integer、Long、Float、String、Object
 */
public class PreferenceFile {

    private static Context mContext;

    private final int mMode;

    private final String mName;


    public PreferenceFile(String mName,int mMode) {
        this.mMode = mMode;
        this.mName = mName;
    }

    public static void init(Context context) {
        mContext = context;
    }
    public static boolean isInit(){
        return mContext != null;
    }
    public SharedPreferences open() {
        if (mContext == null) {
            Log.i("azy", "偏好设置文件打开时mContext为null: ");
//            throw new IllegalArgumentException(
//                    "please init() before open()"
//            );
        }
        return mContext.getSharedPreferences(mName, mMode);
    }
    public  boolean commit(SharedPreferences.Editor editor) {
        if (Build.VERSION.SDK_INT < 9) {
            return editor.commit();
        }
        editor.apply();
        return true;
    }

    public SharedPreference<Boolean> value(String key,Boolean defaultValue) {
        return new SharedPreference<Boolean>(this,key,defaultValue) {
            @Override
            protected Boolean read(SharedPreferences sp) {
                if (sp != null && sp.contains(mKey)) {
                    return Boolean.valueOf(sp.getBoolean(mKey,false));
                }
                return mDefaultValue;
            }

            @Override
            protected void write(SharedPreferences.Editor editor, Boolean value) {
                if (value == null) {
                    throw new IllegalArgumentException(
                            "null cannot be written for <Boolean>"
                    );
                }
                editor.putBoolean(mKey,value.booleanValue());
            }
        };
    }
    public SharedPreference<Integer> value(String key,Integer defaultValue) {
        return new SharedPreference<Integer>(this,key,defaultValue){

            @Override
            protected Integer read(SharedPreferences sp) {
                if (sp != null && sp.contains(mKey)) {
                    return Integer.valueOf(sp.getInt(mKey,0));
                }
                return mDefaultValue;
            }

            @Override
            protected void write(SharedPreferences.Editor editor, Integer value) {
                if (value == null) {
                    throw new IllegalArgumentException(
                            "null cannot be written for <Integer>"
                    );
                }
                editor.putInt(mKey,value.intValue());
            }
        };
    }
    public SharedPreference<Long> value(String key, Long defaultValue) {
        return new SharedPreference<Long>(this, key, defaultValue) {

            @Override
            protected Long read(SharedPreferences sp) {
                if (sp != null && sp.contains(mKey)) {
                    return Long.valueOf(sp.getLong(mKey, 0));
                }
                return mDefaultValue;
            }

            @Override
            protected void write(SharedPreferences.Editor editor, Long value) {
                if (value == null) {
                    throw new IllegalArgumentException(
                            "null cannot be written for <Long>");
                }
                editor.putLong(mKey, value.longValue());
            }

        };
    }
    public SharedPreference<Float> value(String key, Float defaultValue) {
        return new SharedPreference<Float>(this, key, defaultValue) {

            @Override
            protected Float read(SharedPreferences sp) {
                if (sp != null && sp.contains(mKey)) {
                    return Float.valueOf(sp.getLong(mKey, 0));
                }
                return mDefaultValue;
            }

            @Override
            protected void write(SharedPreferences.Editor editor, Float value) {
                if (value == null) {
                    throw new IllegalArgumentException(
                            "null cannot be written for <Long>");
                }
                editor.putFloat(mKey,value.floatValue());
            }

        };
    }

    public SharedPreference<String> value(String key, String defaultValue) {
        return new SharedPreference<String>(this, key, defaultValue) {

            @Override
            protected String read(SharedPreferences sp) {
                if (sp != null && sp.contains(mKey)) {
                    return sp.getString(mKey, null);
                }
                return mDefaultValue;
            }

            @Override
            protected void write(SharedPreferences.Editor editor, String value) {
                editor.putString(mKey, value);
            }
        };
    }
    /**
     * 将对象进行base64编码在SharePref中存取
     *
     */
    public SharedPreference<Object> value(String key, Object object, Object defaultValue) {
        return new SharedPreference<Object>(this,key,defaultValue) {
            @Override
            protected Object read(SharedPreferences sp) {

                if (sp != null && sp.contains(mKey)) {
                    String objectVal = sp.getString(mKey, null);
                    if (TextUtils.isEmpty(objectVal))
                        return null;
                    byte[] buffer = Base64.decode(objectVal, Base64.DEFAULT);
                    ByteArrayInputStream bais = new ByteArrayInputStream(buffer);
                    ObjectInputStream ois = null;
                    Object obj = null;
                    try {
                        ois = new ObjectInputStream(bais);
                        obj = ois.readObject();
                        return obj;
                    } catch (StreamCorruptedException e) {
                        e.printStackTrace();
                    } catch (IOException e) {
                        e.printStackTrace();
                    } catch (ClassNotFoundException e) {
                        e.printStackTrace();
                    } finally {
                        try {
                            if (bais != null) {
                                bais.close();
                            }
                            if (ois != null) {
                                ois.close();
                            }
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
                return null;
            }

            @Override
            protected void write(SharedPreferences.Editor editor, Object value) {
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                ObjectOutputStream out = null;
                try {

                    out = new ObjectOutputStream(baos);
                    out.writeObject(value);
                    String objectVal = new String(Base64.encode(baos.toByteArray(), Base64.DEFAULT));
                    editor.putString(mKey, objectVal);
                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
                    try {
                        if (baos != null) {
                            baos.close();
                        }
                        if (out != null) {
                            out.close();
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        };
    }



}
